package com.example.opengldemo.vertex_shader_more.file_version_3;//������

import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.FloatBuffer;

import android.content.res.Resources;
import android.opengl.GLES20;
import android.opengl.GLES30;

import com.example.opengldemo.util.ShaderUtil;


 class ParticleForDraw {
	int mProgram;
    int muMVPMatrixHandle;
    int mmaxLifeSpan;//
    int muBj;
    int muStartColor;
    int muEndColor;
    int muCameraPosition;
    int muMMatrix;
    int maPositionHandle;
    String mVertexShader;
    String mFragmentShader;
	
    int mProgram0;
    int maPositionHandle0;
    int mtPositionHandle0;//
    int mGroupCountHandle0;
    int mCountHandle0;
    int mLifeSpanStepHandle0;
    
    String mVertexShader0;
    String mFragmentShader0;
    
	FloatBuffer mVertexBuffer;
	FloatBuffer tmVertexBuffer;
	
    int vCount=0;   
    float halfSize;
    
	int mVertexBufferIds[]=new int[2];
	int mVertexBufferId0;
	
	int[] a={0,1};
    int[] b={1,0};
    int index=0;
    
    public ParticleForDraw(Resources mv, float halfSize, float x, float y)
    {    	
    	this.halfSize=halfSize;

    	initShader0(mv);

    	initShader(mv);
    }
   

    public void initVertexData(float[] points,float[] tpoints)
    {
    	int[] buffIds=new int[3];

    	GLES30.glGenBuffers(3, buffIds, 0);

    	this.mVertexBufferIds[0]=buffIds[0];

    	this.mVertexBufferIds[1]=buffIds[1];

    	this.mVertexBufferId0=buffIds[2];
    	

    	this.vCount=points.length/4;
        ByteBuffer vbb = ByteBuffer.allocateDirect(points.length*4);
        vbb.order(ByteOrder.nativeOrder());
        this.mVertexBuffer = vbb.asFloatBuffer();
        this.mVertexBuffer.put(points);
        this.mVertexBuffer.position(0);

    	GLES30.glBindBuffer(GLES30.GL_ARRAY_BUFFER,this.mVertexBufferIds[0]);

    	GLES30.glBufferData(GLES30.GL_ARRAY_BUFFER, points.length*4, this.mVertexBuffer, GLES30.GL_STATIC_DRAW);    

    	GLES30.glBindBuffer(GLES30.GL_ARRAY_BUFFER,mVertexBufferIds[1]);

    	GLES30.glBufferData(GLES30.GL_ARRAY_BUFFER, points.length*4, this.mVertexBuffer, GLES30.GL_STATIC_DRAW);    	

        ByteBuffer vbb0 = ByteBuffer.allocateDirect(tpoints.length*4);
        vbb0.order(ByteOrder.nativeOrder());
        this.tmVertexBuffer = vbb0.asFloatBuffer();
        this.tmVertexBuffer.put(tpoints);
        this.tmVertexBuffer.position(0);

    	GLES30.glBindBuffer(GLES30.GL_ARRAY_BUFFER,this.mVertexBufferId0);

    	GLES30.glBufferData(GLES30.GL_ARRAY_BUFFER, tpoints.length*4, this.tmVertexBuffer, GLES30.GL_STATIC_DRAW);    

    	GLES20.glBindBuffer(GLES20.GL_ARRAY_BUFFER,0);
    }

    public void initShader0(Resources mv)
    {

        mVertexShader0= ShaderUtil.loadFromAssetsFile("vertexmagical/particle/vertex_TransformFeedback.sh", mv);

        mFragmentShader0=ShaderUtil.loadFromAssetsFile("vertexmagical/particle/frag_TransformFeedback.sh", mv);

        mProgram0 = ShaderUtil.createProgram_TransformFeedback(mVertexShader0, mFragmentShader0);

        maPositionHandle0 = GLES30.glGetAttribLocation(mProgram0, "aPosition");

        mtPositionHandle0 = GLES30.glGetAttribLocation(mProgram0, "tPosition");

        mCountHandle0=GLES30.glGetUniformLocation(mProgram0, "count");

        mGroupCountHandle0=GLES30.glGetUniformLocation(mProgram0, "groupCount");

        mLifeSpanStepHandle0=GLES30.glGetUniformLocation(mProgram0, "lifeSpanStep");
        
    }

     public void initShader(Resources mv)
     {

         mVertexShader=ShaderUtil.loadFromAssetsFile("vertexmagical/particle/vertex_particle_version_3.sh", mv);

         mFragmentShader=ShaderUtil.loadFromAssetsFile("vertexmagical/particle/frag_particle_version_3.sh", mv);

         mProgram =ShaderUtil.createProgram(mVertexShader, mFragmentShader);

         maPositionHandle = GLES30.glGetAttribLocation(mProgram, "aPosition");

         muMVPMatrixHandle = GLES30.glGetUniformLocation(mProgram, "uMVPMatrix");

         mmaxLifeSpan=GLES30.glGetUniformLocation(mProgram, "maxLifeSpan");

         muBj=GLES30.glGetUniformLocation(mProgram, "bj");

         muStartColor=GLES30.glGetUniformLocation(mProgram, "startColor");

         muEndColor=GLES30.glGetUniformLocation(mProgram, "endColor");

         muCameraPosition=GLES30.glGetUniformLocation(mProgram, "cameraPosition");

         muMMatrix=GLES30.glGetUniformLocation(mProgram, "uMMatrix");
     }
    
    public void drawSelf0(int count,int groupCount,float lifeSpanStep){

   	 	GLES30.glUseProgram(mProgram0);  

   	 	GLES30.glBindBufferBase(GLES30.GL_TRANSFORM_FEEDBACK_BUFFER, 0, mVertexBufferIds[b[index]]);

   	 	GLES30.glEnable(GLES30.GL_RASTERIZER_DISCARD);

   	 	GLES30.glUniform1i(mCountHandle0, count);

   	 	GLES30.glUniform1i(mGroupCountHandle0, groupCount);

   	 	GLES30.glUniform1f(mLifeSpanStepHandle0, lifeSpanStep);

		GLES30.glEnableVertexAttribArray(maPositionHandle0);  

		GLES30.glEnableVertexAttribArray(mtPositionHandle0);

		GLES30.glBindBuffer(GLES30.GL_ARRAY_BUFFER,mVertexBufferIds[a[index]]); 

		GLES30.glVertexAttribPointer  
		(
				maPositionHandle0,   
				4, 
				GLES30.GL_FLOAT, 
				false,
				4*4,   
				0
		);   		
		

		GLES30.glBindBuffer(GLES30.GL_ARRAY_BUFFER,mVertexBufferId0); 

		GLES30.glVertexAttribPointer  
		(
				mtPositionHandle0,   
				4, 
				GLES30.GL_FLOAT, 
				false,
				4*4,   
				0
		);  
		

		GLES30.glBindBuffer(GLES30.GL_ARRAY_BUFFER,0);

   	 	GLES30.glBeginTransformFeedback(GLES30.GL_POINTS);

        GLES30.glDrawArrays(GLES30.GL_POINTS, 0, vCount);

        GLES30.glEndTransformFeedback();

        GLES30.glDisable(GLES30.GL_RASTERIZER_DISCARD);

        GLES30.glUseProgram(0);

        GLES30.glBindBufferBase(GLES30.GL_TRANSFORM_FEEDBACK_BUFFER, 0, 0);
        
        index++;
		if(index>=2)
		{
			index=0;
		}
    }

    public void drawSelf(int texId,float maxLifeSpan,float[] startColor,float[] endColor)
    {   
         GLES30.glUseProgram(mProgram);  

         GLES30.glUniformMatrix4fv(muMVPMatrixHandle, 1, false, MatrixState.getFinalMatrix(), 0); 
         
         GLES30.glUniform1f(mmaxLifeSpan, maxLifeSpan);

         GLES30.glUniform1f(muBj, halfSize);

         GLES30.glUniform4fv(muStartColor, 1, startColor, 0);

         GLES30.glUniform4fv(muEndColor, 1, endColor, 0);

         GLES30.glUniform3f(muCameraPosition,MatrixState.cx, MatrixState.cy, MatrixState.cz);

         GLES30.glUniformMatrix4fv(muMMatrix, 1, false, MatrixState.getMMatrix(), 0); 

 		 GLES30.glEnableVertexAttribArray(maPositionHandle);  

 		 GLES30.glBindBuffer(GLES30.GL_ARRAY_BUFFER,mVertexBufferIds[a[index]]); 

 		 GLES30.glVertexAttribPointer  
 		 (
 				maPositionHandle,   
 				4, 
 				GLES30.GL_FLOAT, 
 				false,
 				4*4,   
 				0
 		 ); 

         GLES30.glActiveTexture(GLES30.GL_TEXTURE0);
         GLES30.glBindTexture(GLES30.GL_TEXTURE_2D, texId);

         GLES30.glDrawArrays(GLES30.GL_POINTS, 0, vCount); 

 		 GLES30.glBindBuffer(GLES30.GL_ARRAY_BUFFER,0);
    }
}
